package com.dunshanasync.config;
import com.google.common.hash.Hashing;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.springframework.context.annotation.Configuration;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.zip.CRC32;
/**
 * @author .dunshan
 * @program: dunshan-pef
 * @description: 一致性哈希算法
 * @date 2021-08-09 09:17:52
 */
@Slf4j
public class ConsistentHashShardingAlgorithm implements PreciseShardingAlgorithm<Comparable<?>> {

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Comparable<?>> preciseShardingValue) {

        Integer shardingCount = collection.size();
        String suffix = this.shardSuffix(preciseShardingValue.getValue().toString(),shardingCount);
        for (String tbname : collection){
            if (tbname.endsWith(suffix)){
                log.info("sharding table is :{}",tbname);
                return tbname;
            }
        }
        return null;
    }

    /**
     * 根据key获取分表后缀
     * @param hashKey
     * @return
     */
    public static String shardSuffix(Serializable hashKey, Integer count) {
        CRC32 crc32 = new CRC32();
        crc32.update(String.valueOf(hashKey).getBytes(StandardCharsets.UTF_8));

        return String.valueOf(Hashing.consistentHash(crc32.getValue(), count));
    }
}
